package _chan

//
//import (
//	"bufio"
//	"container/heap"
//	"fmt"
//	"github.com/gin-gonic/gin"
//	"image"
//	"math"
//	"os"
//	"pure/app/utils"
//	"strconv"
//	"strings"
//	"sync"
//	"time"
//)
//
//type ht struct {
//	landJx map[string]struct{}
//	landCl map[string]struct{}
//}
//
//var Ht = ht{}
//
//type HtAStarReq struct {
//	Start []float64 `json:"start"`
//	End   []float64 `json:"end"`
//}
//
//type Config struct {
//	Motions [][2]float64
//}
//
//// var landMap = AllWhiteIntTest(120.0879, 36.2606, 0.0001, 10000)
//// var landMap = AllWhiteIntTest(116, 38, 0.0001, 10000)
//var landMap = make(map[[2]int]struct{}, 200000)
//var gangkouMap = readGangkouMap()
//
//// var landMapBig = AllWhiteIntTest(116, 38, 0.001, 1000)
//var landMapBig = readLandTxt("./public/image/0.001.txt")
//var bufferMap = readLandTxt("./public/image/buffer.txt")
//
//var bufferMapXiao = readLandTxt("./public/image/buffer.txt")
//var txtM = sync.Mutex{}
//
//var items [][]float64
//
//// 定义一个计数的通道，最大并发数为10
//// 由于有分段的设计，找一段的方法抽出来
//func findOnePath(req HtAStarReq, angleNum int, step float64, isOut bool, isEndBuffer bool) []string {
//	costMap := sync.Map{}
//	costMap.Store([2]int{
//		int(math.Round(req.Start[0] * 10000)),
//		int(math.Round(req.Start[1] * 10000)),
//	}, 0.0)
//	relationMap := sync.Map{}
//	relationMap.Store([2]int{
//		int(math.Round(req.Start[0] * 10000)),
//		int(math.Round(req.Start[1] * 10000)),
//	}, [3]int{
//		int(math.Round(req.Start[0] * 10000)),
//		int(math.Round(req.Start[1] * 10000)),
//		0,
//	})
//	closeMap := sync.Map{}
//
//	openList := &MinHeap{}
//	heap.Init(openList)
//	heap.Push(openList, []float64{0, req.Start[0], req.Start[1], -1})
//	motions := GetMotions(angleNum)
//	var wg sync.WaitGroup
//	//var chNum = make(chan bool, 10)
//	num := 0
//	var chHeap = make(chan []float64, 100000)
//	isFind := false
//	var mm sync.Mutex
//
//	go func() {
//		wg.Add(1)
//		for {
//			if isFind {
//				break
//			}
//			if openList.Len() > 0 {
//				mm.Lock()
//				chHeap <- heap.Pop(openList).([]float64)
//				mm.Unlock()
//			}
//		}
//		close(chHeap)
//		wg.Done()
//	}()
//	for i := 0; i < 5; i++ {
//		wg.Add(1)
//		go func() {
//			defer wg.Done()
//			for minItem := range chHeap {
//				num++
//				closeMap.Store([2]int{
//					int(minItem[1] * 10000),
//					int(minItem[2] * 10000),
//				}, struct{}{})
//				if isFind {
//					break
//				}
//				//fmt.Println(minItem)
//				//time.Sleep(time.Second)
//				//motions[0] = []float64{9999, 9999, 9999}
//
//				if math.Abs(minItem[1]-req.End[0]) < 0.01 && math.Abs(minItem[2]-req.End[1]) < 0.01 {
//					isFind = true
//					fmt.Println("找到了", minItem, num)
//					path := getPath(relationMap, [2]int{int(math.Round(req.Start[0] * 10000)), int(math.Round(req.Start[1] * 10000))}, [2]int{int(math.Round(minItem[1] * 10000)), int(math.Round(minItem[2] * 10000))}, [2]int{int(math.Round(req.End[0] * 10000)), int(math.Round(req.End[1] * 10000))})
//					fmt.Println("路径：", path)
//				}
//				for idx, sN := range getNeighbor(minItem, motions, step, isOut, 333) {
//					if sN[0] < 800 {
//						latInt := int(math.Round(sN[0] * 10000))
//						lonInt := int(math.Round(sN[1] * 10000))
//
//						minLatInt := int(math.Round(minItem[1] * 10000))
//						minLonInt := int(math.Round(minItem[2] * 10000))
//
//						//	判断costMap中是否存在[2]int{minLatInt, minLonInt}
//						_, okClose := costMap.Load([2]int{
//							latInt,
//							lonInt,
//						})
//
//						if okClose {
//							continue
//						}
//
//						oldCost, _ := costMap.Load([2]int{
//							minLatInt,
//							minLonInt,
//						})
//						newCost := oldCost.(float64) + motions[idx][2]*step
//
//						//	判断costMap中是否存在[2]int{latInt, lonInt}
//						_, ok := costMap.Load([2]int{
//							latInt,
//							lonInt,
//						})
//						if !ok {
//							costMap.Store([2]int{
//								latInt,
//								lonInt,
//							}, 999.0)
//						}
//
//						lastCost, _ := costMap.Load([2]int{
//							latInt,
//							lonInt,
//						})
//
//						if newCost < lastCost.(float64) {
//							costMap.Store([2]int{
//								latInt,
//								lonInt,
//							}, newCost)
//							relationMap.Store([2]int{
//								latInt,
//								lonInt,
//							}, [3]int{
//								minLatInt,
//								minLonInt,
//								idx,
//							})
//							mm.Lock()
//							heap.Push(openList, []float64{newCost + getDistance(sN[0], sN[1], req.End[0], req.End[1]), sN[0], sN[1], float64(idx)})
//							mm.Unlock()
//						}
//					}
//				}
//			}
//		}()
//	}
//	wg.Wait()
//	return []string{}
//}
//
//var idxArr [17]int
//
//// HtAStar 开始
//func (ctl *ht) HtAStar(c *gin.Context) {
//	items = [][]float64{}
//	allNum = 0
//	at1 := time.Now().UnixNano()
//	var req HtAStarReq
//	_ = c.ShouldBind(&req)
//	//打印起始点和目标点
//	fmt.Println("起始点---->", req.Start, "目标点---->", req.End)
//
//	//t2 := time.Now().UnixNano()
//	//txtM.Lock()
//	//landMap = readLandTxt("./public/image/0.05/" + utils.Float64ToFixedStr(float64(int(req.Start[0]*10)+1)/10, 1) + "_" + utils.Float64ToFixedStr(float64(int(req.Start[1]*10))/10, 1) + ".txt")
//	//fmt.Println("./public/image/0.05/" + utils.Float64ToFixedStr(float64(int(req.Start[0]*10)+1)/10, 1) + "_" + utils.Float64ToFixedStr(float64(int(req.Start[1]*10))/10, 1) + ".txt")
//	//txtM.Unlock()
//	//fmt.Println((time.Now().UnixNano() - t2) / 1e6)
//
//	//cellSize:默认精度 step:搜索步长 bufferSize:缓冲区大小
//	//cellSize := 0.0001
//	step := 0.006
//	angleNum := 32
//	//bufferSize := 0.01
//
//	allT1 = 0
//	allT2 = 0
//	allT3 = 0
//	idxArr = [17]int{}
//	//找到缓冲区外的点
//	//t1 := time.Now().UnixNano()
//	startBuffer, endBuffer := getPointBuffer(&req, step*1.5)
//	//t11 := time.Now().UnixNano()
//	//fmt.Println("冲出缓冲区用时：", (t11-t1)/1e6, "毫秒")
//
//	_, isBuffer := bufferMapXiao[[2]int{
//		int(endBuffer[0]*100 + 1),
//		int(endBuffer[1] * 100),
//	}]
//
//	var pathStart, pathEnd, pathMid, PathResult []string
//	var pathWg sync.WaitGroup
//	if startBuffer[0] != req.Start[0] || startBuffer[1] != req.Start[1] {
//		go func() {
//			pathWg.Add(1)
//			//t2 := time.Now().UnixNano()
//			var reqStart HtAStarReq
//			reqStart.Start = req.Start
//			reqStart.End = startBuffer
//			_, islll := gangkouMap[[2]int{
//				int(req.Start[0] * 10000),
//				int(req.Start[1] * 10000),
//			}]
//
//			if islll {
//				//fmt.Println(getNotLan(req.Start, req.End))
//				reqStart.Start = getNotLan(req.Start, req.End)
//			}
//			pathStart = findOnePath(reqStart, angleNum, 0.001, false, true)
//			pathStart = append(pathStart, utils.Float64ToFixedStr(req.Start[0], 4)+","+utils.Float64ToFixedStr(req.Start[1], 4))
//			//t22 := time.Now().UnixNano()
//			//fmt.Println("起始点用时：", (t22-t2)/1e6)
//			pathWg.Done()
//		}()
//	}
//
//	if endBuffer[0] != req.End[0] || endBuffer[1] != req.End[1] {
//		go func() {
//			pathWg.Add(1)
//			var reqEnd HtAStarReq
//			reqEnd.Start = endBuffer
//			reqEnd.End = req.End
//			pathEnd = findOnePath(reqEnd, angleNum, 0.001, false, true)
//			pathWg.Done()
//		}()
//	}
//
//	//t4 := time.Now().UnixNano()
//	var reqMid HtAStarReq
//	reqMid.Start = startBuffer
//	reqMid.End = endBuffer
//	pathMid = findOnePath(reqMid, angleNum, step, true, isBuffer)
//	//t44 := time.Now().UnixNano()
//	//fmt.Println("中间点用时：", (t44-t4)/1e6)
//	//fmt.Println("获取邻域：", allT1/1e6)
//	//fmt.Println("mmm：", allT2)
//	//fmt.Println("关顾：", idxArr)
//	//fmt.Println("特殊点：", inNum)
//
//	//var points []utils.Point
//	//
//	//for _, v := range pathMid {
//	//	pointArr := strings.Split(v, ",")
//	//	lat, _ := strconv.ParseFloat(pointArr[0], 64)
//	//	lon, _ := strconv.ParseFloat(pointArr[1], 64)
//	//	points = append(points, utils.Point{X: lat, Y: lon})
//	//}
//	//
//	//var midPoints []string
//	//for _, v := range utils.DrawBezierCurve(points) {
//	//	//拼接v.X, v.Y,转为字符串
//	//	str := utils.Float64ToStr(v.X) + "," + utils.Float64ToStr(v.Y)
//	//	midPoints = append(midPoints, str)
//
//	//}
//
//	//midPoints := utils.SmoothBezier(pathMid)
//	//midPoints := utils.Cnm(pathMid)
//	//points := []string{"10,20", "30,40", "50,60", "70,80"}
//
//	//curve := utils.BezierCurve(points)
//	//
//	//fmt.Println(curve)
//
//	pathWg.Wait()
//
//	PathResult = append(PathResult, pathEnd...)
//	PathResult = append(PathResult, pathMid...)
//	PathResult = append(PathResult, pathStart...)
//
//	at2 := time.Now().UnixNano()
//	c.JSON(200, gin.H{
//		"code": 0,
//		"msg":  "成功",
//		"data": gin.H{
//			"lines":       PathResult,
//			"startBuffer": startBuffer,
//			"endBuffer":   endBuffer,
//			"t":           (at2 - at1) / 1e6,
//			"num":         allNum,
//			"gdNum":       len(pathMid) + len(pathStart) + len(pathEnd),
//			"items":       items,
//		},
//	})
//}
//
//var jpsArr = [][]int{{}}
//
////var jpsArr = []map[int]int{
////	{
////		9:  1,
////		11: 1,
////		12: 1,
////		13: 1,
////		14: 2,
////		15: 2,
////	},
////}
//
//func GetMotions8(angle int) [][]float64 {
//	var motions [][]float64 = [][]float64{{1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}}
//	return motions
//}
//
//// GetMotions 获取n方向
//func GetMotions(angle int) [][]float64 {
//	var motions [][]float64
//	//motions = append(motions, []float64{})
//	//m32 := [][]float64{{1, 0.25}, {0.75, 0.5}, {0.5, 0.75}, {0.25, 1}, {-0.25, 1}, {-0.5, 0.75}, {-0.75, 0.5}, {-1, 0.25}, {-1, -0.25}, {-0.75, -0.5}, {-0.5, -0.75}, {-0.25, -1}, {0.25, -1}, {0.5, -0.75}, {0.75, -0.5}, {1, -0.25}}
//	////m32 := [][]float64{{0.25, 1}, {0.5, 0.75}, {0.75, 0.5}, {1, 0.25}, {1, -0.25}, {0.75, -0.5}, {0.5, -0.75}, {0.25, -1}, {-0.25, -1}, {-0.5, -0.75}, {-0.75, -0.5}, {-1, -0.25}, {-1, 0.25}, {-0.75, 0.5}, {-0.5, 0.75}, {-0.25, 1}}
//	//m16 := [][]float64{{0.25, 0.5}, {0.5, 0.25}, {0.5, -0.25}, {0.25, -0.5}, {-0.25, -0.5}, {-0.5, -0.25}, {-0.5, 0.25}, {-0.25, 0.5}}
//	//m8 := [][]float64{{0, 0.25}, {0.25, 0.25}, {0.25, 0}, {0.25, -0.25}, {0, -0.25}, {-0.25, -0.25}, {-0.25, 0}, {-0.25, 0.25}}
//	//
//	////将m32,m16,m8合并
//	//motions = append(motions, m32...)
//	//motions = append(motions, m16...)
//	//motions = append(motions, m8...)
//	//
//	//for i, v := range motions {
//	//	if i == 0 {
//	//		continue
//	//	} else {
//	//		l := math.Sqrt(math.Pow(v[0], 2) + math.Pow(v[1], 2))
//	//		motions[i] = append(motions[i], l)
//	//	}
//	//}
//
//	//文献参考的m16
//	//m16 := [][]float64{{0, 0.5}, {0.5, 1}, {0.5, 0.5}, {1, 0.5}, {0.5, 0}, {1, -0.5}, {0.5, -0.5}, {0.5, -1}, {0, -0.5}, {-0.5, -1}, {-0.5, -0.5}, {-1, -0.5}, {-0.5, 0}, {-1, 0.5}, {-0.5, 0.5}, {-0.5, 1}}
//	//正常用这个
//	m16 := [][]float64{{1, 0.5}, {0.5, 1}, {-0.5, 1}, {-1, 0.5}, {-1, -0.5}, {-0.5, -1}, {0.5, -1}, {1, -0.5}, {0.5, 0}, {0.5, 0.5}, {0, 0.5}, {-0.5, 0.5}, {-0.5, 0}, {-0.5, -0.5}, {0, -0.5}, {0.5, -0.5}}
//	//m8 := [][]float64{{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}}
//
//	//m16 := [][]float64{{1, 0}, {1, 0.5}, {1, 1}, {0.5, 1}, {0, 1}, {-0.5, 1}, {-1, 1}, {-1, 0.5}, {-1, 0}, {-1, -0.5}, {-1, -1}, {-0.5, -1}, {0, -1}, {0.5, -1}, {1, -1}, {1, -0.5}}
//	//m16 := [][]float64{{0, 1}, {0.5, 1}, {1, 1}, {1, 0.5}, {1, 0}, {1, -0.5}, {1, -1}, {0.5, -1}, {0, -1}, {-0.5, -1}, {-1, -1}, {-1, -0.5}, {-1, 0}, {-1, 0.5}, {-1, 1}, {-0.5, 1}}
//	//m32 := [][]float64{{0, 1}, {0.25, 1}, {0.5, 1}, {0.75, 1}, {1, 1}, {1, 0.75}, {1, 0.5}, {1, 0.25}, {1, 0}, {1, -0.25}, {1, -0.5}, {1, -0.75}, {1, -1}, {0.75, -1}, {0.5, -1}, {0.25, -1}, {0, -1}, {-0.25, -1}, {-0.5, -1}, {-0.75, -1}, {-1, -1}, {-1, -0.75}, {-1, -0.5}, {-1, -0.25}, {-1, 0}, {-1, 0.25}, {-1, 0.5}, {-1, 0.75}, {-1, 1}, {-0.75, 1}, {-0.5, 1}, {-0.25, 1}}
//	////m1 := [][]float64{{1, 0}, {1, 0.25}, {1, 0.5}, {1, 0.75}, {0.75, 1}, {0.5, 1}, {0.25, 1}, {0, 1}, {-0.25, 1}, {-0.5, 1}, {-0.75, 1}, {-1, 1}, {-1, 0.75}, {-1, 0.5}, {-1, 0.25}, {-1, 0}, {-1, -0.25}, {-1, -0.5}, {-1, -0.75}, {-1, -1}, {-0.75, -1}, {-0.5, -1}, {-0.25, -1}, {0, -1}, {0.25, -1}, {0.5, -1}, {0.75, -1}, {1, -1}, {1, -0.75}, {1, -0.5}, {1, -0.25}}
//	for _, v := range m16 {
//		l := math.Sqrt(math.Pow(v[0], 2) + math.Pow(v[1], 2))
//		motions = append(motions, []float64{v[0], v[1], l})
//	}
//
//	//offset := 8/angle
//	//point8 := [][]float64{{0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}, {-1, 0}, {-1, 1}, {0, 1}}
//	//idx := 0
//	//for {
//	//	if idx == 8 {
//	//		break
//	//	}
//	//	latLonIdx := 0
//	//	point := point8[idx]
//	//	if math.Abs(point8[idx][0]) != 1 || math.Abs(point8[idx+1][0]) != 1 {
//	//		latLonIdx = 0
//	//		point = []float64{point8[idx][0], point8[idx][1]}
//	//	} else if math.Abs(point8[idx][1]) != 1 || math.Abs(point8[idx+1][1]) != 1 {
//	//		latLonIdx = 1
//	//	} else {
//	//		idx++
//	//	}
//	//}
//	//for
//	//for i:=0;i<angle/8;i++ {
//	//	for j:=1;j<=angle/8
//	//}
//	//return motions
//	//for i := 0; i < angle; i++ {
//	//	motions = append(motions, []float64{math.Cos(float64(i) * 2 * math.Pi / float64(angle)), math.Sin(float64(i) * 2 * math.Pi / float64(angle))})
//	//}
//	return motions
//
//	//返回矩形32方向
//	//return [][2]float64{{1, 0}, {1, 0.25}, {1, 0.5}, {1, 0.75}, {0.75, 1}, {0.5, 1}, {0.25, 1}, {0, 1}, {-0.25, 1}, {-0.5, 1}, {-0.75, 1}, {-1, 1}, {-1, 0.75}, {-1, 0.5}, {-1, 0.25}, {-1, 0}, {-1, -0.25}, {-1, -0.5}, {-1, -0.75}, {-1, -1}, {-0.75, -1}, {-0.5, -1}, {-0.25, -1}, {0, -1}, {0.25, -1}, {0.5, -1}, {0.75, -1}, {1, -1}, {1, -0.75}, {1, -0.5}, {1, -0.25}}
//}
//
//func GetMotions1(numDirections int) [][]float64 {
//	directions := make([][]float64, numDirections)
//
//	for i := 0; i < numDirections; i++ {
//		angle := 2 * math.Pi * float64(i) / float64(numDirections)
//		x := math.Cos(angle)
//		y := math.Sin(angle)
//		l := math.Sqrt(math.Pow(x, 2) + math.Pow(y, 2))
//		directions[i] = []float64{x, y, l}
//	}
//	return directions
//}
//
//// MinHeap 小顶堆
//type MinHeap [][]float64
//
//func (h MinHeap) Len() int      { return len(h) }
//func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
//func (h MinHeap) Less(i, j int) bool {
//	return h[i][0] < h[j][0]
//} // 小顶堆
//func (h *MinHeap) Push(x interface{}) {
//	*h = append(*h, x.([]float64))
//}
//func (h *MinHeap) Pop() interface{} {
//	old := *h
//	n := len(old)
//	x := old[n-1]
//	*h = old[0 : n-1]
//	return x
//}
//
//func includesNumber(number, target, tolerance int) bool {
//	//diff := math.Abs(number - target)
//	//return diff <= tolerance
//
//	return math.Abs(float64(number)-float64(target)) <= float64(tolerance)
//}
//
//func AllWhiteIntTest(minLng, maxLat, step float64, precision float64) map[[2]int]struct{} {
//	//120.38669616044902 120.08785992 36.260629574755185 35.96465704
//	wt := time.Now().UnixNano()
//	landM := make(map[[2]int]struct{})
//	f1, _ := os.Open("./public/image/qd.png")
//	//f1, _ := os.Open("./public/image/yh.png")
//
//	num := 0
//
//	defer f1.Close()
//	img1, _, _ := image.Decode(f1)
//
//	maxX, maxY := img1.Bounds().Max.X, img1.Bounds().Max.Y
//
//	wt1 := time.Now().UnixNano()
//	fmt.Println("用时：", (wt1-wt)/1e6)
//
//	//colorArr := [][3]uint32{}
//
//	for i := 0; i < maxX; i = i + (int(step * 10000)) {
//		for j := 0; j < maxY; j = j + (int(step * 10000)) {
//			r, g, b, _ := img1.At(i, j).RGBA()
//			num++
//
//			//isCunzai := false
//			//for _, v := range colorArr {
//			//	if r == v[0] && g == v[1] && b == v[2] {
//			//		isCunzai = true
//			//		break
//			//	}
//			//}
//			//if !isCunzai {
//			//	colorArr = append(colorArr, [3]uint32{r, g, b})
//			//}
//			if r == 0 && g == 0 && b == 0 {
//				continue
//			} else {
//
//				lng := float64(i)*0.0001 + minLng
//				lat := maxLat - float64(j)*0.0001
//				//保持先lat后lng
//				landM[[2]int{
//					int(math.Round(lat * precision)),
//					int(math.Round(lng * precision)),
//				}] = struct{}{}
//			}
//		}
//	}
//
//	fmt.Println(num)
//
//	return landM
//}
//
//var grayNum = 0
//var landNum = 0
//var allNum = 0
//var effectNum = 0
//
//var allT1 = 0
//var allT2 = 0
//var allT3 = 0
//
//// 根据方向获取一个点的所有可以的邻居
//func getNeighbor(minItem []float64, motions [][]float64, step float64, isOut bool, angleGUji float64) [][2]float64 {
//	//lastIdx := int(minItem[3])
//	//if lastIdx == 1 || lastIdx == 5 || lastIdx == 9 || lastIdx == 13 {
//	//	//	遍历jpsArr[0][0]
//	//	for _, v := range jpsArr[0] {
//	//		idx := lastIdx - 1 + v
//	//		if idx > 16 {
//	//			idx = idx - 16
//	//		}
//	//		motions[idx] = []float64{-10, 0, 0}
//	//	}
//	//} else if lastIdx == 2 || lastIdx == 4 || lastIdx == 6 || lastIdx == 8 || lastIdx == 10 || lastIdx == 12 || lastIdx == 816 {
//	//
//	//}
//	//var list [][2]float64
//	list := make([][2]float64, 0, 33)
//
//	//precision := 100.0
//	//gridNum := 30000
//
//	//_, isBuffer := bufferMapXiao[[2]int{
//	//	int(minItem[1]*1000 + 1),
//	//	int(minItem[2] * 1000),
//	//}]
//	//if !isBuffer {
//	//	//precision = 1000.0
//	//	////step = 0.01
//	//	gridNum = 500
//	//	//step = 0.01
//	//}
//
//	t11 := time.Now().UnixNano()
//
//	//fmt.Println(motions)
//	//fmt.Println(weakMap)
//	//fmt.Println(angleGUji)
//	//time.Sleep(time.Second)
//	ratio1 := 1.0
//	for _, offset := range motions {
//
//		//我也不太知道为啥放大之后效果更好!!! 现在知道了，只有在估计距离小于实际距离时候才可以达到整体最优
//		lat := minItem[1] + offset[1]*step*ratio1
//		lon := minItem[2] + offset[0]*step*ratio1
//
//		//_, isClose := closeMap[[2]int{
//		//	int(lat * 10000),
//		//	int(lon * 10000),
//		//}]
//		//
//		//if isClose {
//		//	continue
//		//}
//
//		//只在中间那段用地图大格子
//		isLand := false
//
//		//isBufferXiao := false
//		if isOut {
//
//			_, isLand = landMapBig[[2]int{
//				int(lat*1000 + 1),
//				int(lon * 1000),
//			}]
//
//		} else {
//			//_, isLand = gangkouMap[[2]int{
//			//	int(lat * 10000),
//			//	int(lon * 10000),
//			//}]
//			for _, v := range GetMotions8(8) {
//				_, isLandTep := gangkouMap[[2]int{
//					int(lat*10000 + v[1]*2),
//					int(lon*10000 + v[0]*2),
//				}]
//				if isLandTep {
//					isLand = true
//					break
//				}
//			}
//
//		}
//
//		if !isLand {
//			list = append(list, [2]float64{utils.Float64Fixed(lat, 4), utils.Float64Fixed(lon, 4)})
//
//		} else {
//			//冲出缓冲区了再严格判断，如果有一个点还在地图上，进判断距离陆地太近，直接退出
//			if isOut {
//				inNum++
//				//清空list
//				//for i := 0; i < 34; i++ {
//				//	list = append(list, [2]float64{99999.0, 99999.0})
//				//}
//				list = [][2]float64{}
//
//				break
//			} else {
//				list = append(list, [2]float64{999.0, 999.0})
//			}
//
//			//list = [][2]float64{}
//			//
//			//break
//		}
//
//	}
//	if minItem[3] == 0 && isOut && len(list) != 0 {
//		list = [][2]float64{list[0]}
//	}
//	if minItem[3] == 0 {
//		allT2++
//	}
//	t12 := time.Now().UnixNano()
//	allT1 += int(t12 - t11)
//
//	//fmt.Println(len(list))
//	//time.Sleep(time.Second)
//	return list
//}
//
//var inNum = 0
//
//// 对minItem进行正方形涂灰
//func paintGray(minItem []float64, grayMap map[[2]int]int, step, cellSize float64) {
//	//cellSize = 0.0001
//	//offset := step * 0.65
//	//for i := minItem[1] - offset; i < minItem[1]+offset; i += cellSize {
//	//	for j := minItem[2] - offset; j < minItem[2]+offset; j += cellSize {
//	//		//grayMap[utils.Float64ToFixedStr(i, 4)+","+utils.Float64ToFixedStr(j, 4)] = struct{}{}
//	//
//	//		grayMap[[2]int{
//	//			int(i * 10000),
//	//			int(j * 10000),
//	//		}] = struct{}{}
//	//	}
//	//}
//
//	//大格点版本
//	//offset := step * 0.7
//	//for i := minItem[1] - offset + 0.002; i <= minItem[1]+offset; i += cellSize {
//	//	for j := minItem[2] - offset + 0.001; j <= minItem[2]+offset-0.001; j += cellSize {
//	//		grayMap[[2]int{
//	//			int(i * 1000),
//	//			int(j * 1000),
//	//		}] = struct{}{}
//	//	}
//	//}
//
//	//大格点版本+整数   和上面那个速度没区别
//	offset := 50
//	latInt := int(math.Round(minItem[1] * 10000))
//	lonInt := int(math.Round(minItem[2] * 10000))
//
//	//for i := latInt - offset + 20; i <= latInt+offset; i += 10 {
//	//	for j := lonInt - offset + 10; j <= lonInt+offset-10; j += 10 {
//	//		grayMap[[2]int{
//	//			i / 10,
//	//			j / 10,
//	//		}] = struct{}{}
//	//	}
//	//}
//
//	for i := latInt - offset + 20; i <= latInt+offset; i += 10 {
//		for j := lonInt - offset + 10; j <= lonInt+offset-10; j += 10 {
//			//grayMap[[2]int{
//			//	i / 10,
//			//	j / 10,
//			//}] = struct{}{}
//			_, isGray := grayMap[[2]int{
//				i / 10,
//				j / 10,
//			}]
//			if !isGray {
//				grayMap[[2]int{
//					i / 10,
//					j / 10,
//				}] = 100
//			}
//
//		}
//	}
//
//	//grayMap[[2]int{
//	//	latInt / 10,
//	//	lonInt / 10,
//	//}] = struct{}{}
//}
//
//func getDistance(lat1, lng1, lat2, lng2 float64) float64 {
//	return math.Sqrt(math.Pow(lat1-lat2, 2) + math.Pow(lng1-lng2, 2))
//	//zxDis := math.Sqrt(math.Pow(lat1-lat2, 2) + math.Pow(lng1-lng2, 2))
//	//mhdDis := math.Abs(lat1-lat2) + math.Abs(lng1-lng2)
//	////w := 1 + (zxDis)
//	//return 0.4*mhdDis + 0.6*zxDis
//	//	欧式距离
//	//return math.Abs(lat1-lat2) + math.Abs(lng1-lng2)
//}
//
//func getDistanceWeight(lat1, lng1, lat2, lng2 float64, minItem []float64) float64 {
//	//return math.Sqrt(math.Pow(lat1-lat2, 2) + math.Pow(lng1-lng2, 2))
//	//	计算lat1, lng1, lat2, lng2连线的角度
//	//angle := math.Atan2(lat2-lat1, lng2-lng1)
//	//	计算lat2, lng2, minItem[1], minItem[2]连线的角度
//	angle2 := math.Atan2(minItem[1]-lat2, minItem[2]-lng2)
//	//	计算两个角度的差值
//	//angle3 := math.Abs(angle - angle2)
//	//fmt.Println(angle2 * 180 / math.Pi)
//	//if angle3 < math.Pi {
//	//	return math.Sqrt(math.Pow(lat1-lat2, 2)+math.Pow(lng1-lng2, 2)) * 1
//	//} else {
//	//	return math.Sqrt(math.Pow(lat1-lat2, 2)+math.Pow(lng1-lng2, 2)) * 1
//	//
//	//}
//	angle2 = angle2 * 180 / math.Pi
//	if angle2 < 0 {
//		angle2 = 360 + angle2
//	}
//	if angle2 > 45 && angle2 < 135 {
//		return math.Sqrt(math.Pow(lat1-lat2, 2)+math.Pow(lng1-lng2, 2)) * 1
//	} else {
//		return math.Sqrt(math.Pow(lat1-lat2, 2)+math.Pow(lng1-lng2, 2)) * 1
//	}
//}
//
//// 判断两点之间是否有障碍物
//func isInLand(p1, p2 [2]int, landMap map[[2]int]struct{}) bool {
//	// 获取直线路径上的所有点
//	points := getPointsOnLine(p1, p2)
//
//	// 检查每个点是否存在于陆地地图中
//	for _, point := range points {
//		if _, ok := landMap[point]; ok {
//			return true
//		}
//	}
//
//	return false
//}
//
//// 获取两点之间的直线路径上的所有点
//// 获取两点之间的直线路径上的每隔5个单位取一个点
//func getPointsOnLine(p1, p2 [2]int) [][2]int {
//	points := make([][2]int, 15)
//
//	// 提取两点的坐标
//	x1, y1 := p1[0], p1[1]
//	x2, y2 := p2[0], p2[1]
//
//	//计算直线路径的总距离
//	dx := abs(x2 - x1)
//	dy := abs(y2 - y1)
//	distance := max(dx, dy)
//
//	// 计算每个单位距离的增量
//	xIncrement := float64(x2-x1) / float64(distance)
//	yIncrement := float64(y2-y1) / float64(distance)
//
//	// 添加起始点
//	points = append(points, [2]int{x1, y1})
//
//	//每隔5个单位取一个点，并添加到结果列表中
//	for i := 1; i <= distance; i += 10 {
//		x := int(float64(x1) + float64(i)*xIncrement)
//		y := int(float64(y1) + float64(i)*yIncrement)
//		points = append(points, [2]int{x, y})
//		//大格点版本
//		//points = append(points, [2]int{x / 10, y / 10})
//	}
//
//	//x1, y1 := p1[0], p1[1]
//	//x2, y2 := p2[0], p2[1]
//	//dx := x2 - x1
//	//dy := y2 - y1
//	//for i := 1; i < 10; i++ {
//	//	points = append(points, [2]int{(x1 + dx*i/10) / 10, (y1 + dy*i/10) / 10})
//	//}
//
//	return points
//}
//
//// 返回两个整数中的最大值
//func max(a, b int) int {
//	if a > b {
//		return a
//	}
//	return b
//}
//
//// 计算整数的绝对值
//func abs(n int) int {
//	if n < 0 {
//		return -n
//	}
//	return n
//}
//
//// 根据relationMap获取路径
//func getPath(relationMap sync.Map, start, endMin, end [2]int) []string {
//	// 从终点开始回溯路径
//	//path := make([]string, 0)
//	current := end
//	for {
//		// 获取当前节点的前一个节点
//		pre, ok := relationMap.Load(current)
//		if !ok {
//			break
//		}
//		prePoint := pre.([2]int)
//
//		fmt.Println("prePoint", prePoint)
//	}
//
//	return []string{}
//}
//
//// getPointBuffer 算出起始点和目标点的缓冲区外点。如果本身就在缓冲区外就不用算了
//func getPointBuffer(req *HtAStarReq, step float64) ([]float64, []float64) {
//	//var motions [][2]float64
//	//angle := 32
//	//每次扩展的长度
//	//step := 0.005
//	//for i := 0; i < angle; i++ {
//	//	motions = append(motions, [2]float64{math.Cos(float64(i) * 2 * math.Pi / float64(angle)), math.Sin(float64(i) * 2 * math.Pi / float64(angle))})
//	//}
//
//	motions := GetMotions(16)
//	motions = motions[1:]
//	//删除motions第一个元素
//
//	var startBuffer []float64
//	var endBuffer []float64
//	wgBuffer := sync.WaitGroup{}
//	wgBuffer.Add(2)
//	for i, v := range [2][]float64{req.Start, req.End} {
//		go func(v []float64, i int) {
//			if i == 0 {
//				//startBuffer = func1Five(motions, step, [][]float64{v}, req.End)
//				//var ch1 = make(chan []float64, 10)
//				//ch1 <- []float64{v[0], v[1], -1}
//				//close(ch1)
//				////grayStart := make(map[[2]int]int, 2000)
//				//grayStart := sync.Map{}
//				//
//				//startBuffer = func1(motions, step, ch1, req.End, &grayStart, req.Start)
//				startBuffer = func8(motions, step, map[[2]float64]int{
//					{v[0], v[1]}: 1,
//				}, req.End, &sync.Map{}, req.Start)
//				//_, isLand := landMapBig[[2]int{
//				//	int(v[0]*1000 + 1),
//				//	int(v[1] * 1000),
//				//}]
//				//if !isLand {
//				//	startBuffer = func8(motions, step, v, req.End)
//				//} else {
//				//	startBuffer = v
//				//}
//
//			} else {
//				//endBuffer = func1Five(motions, step, [][]float64{v}, req.Start)
//				//var ch1 = make(chan []float64, 10)
//				//ch1 <- []float64{v[0], v[1], -1}
//				//close(ch1)
//				//grayEnd := sync.Map{}
//				//endBuffer = func1(motions, step, ch1, req.Start, &grayEnd, req.End)
//
//				endBuffer = func8(motions, step, map[[2]float64]int{
//					{v[0], v[1]}: 1,
//				}, req.Start, &sync.Map{}, req.End)
//
//				//endBuffer = func8(motions, step, v, req.Start)
//
//				//_, isLand := landMapBig[[2]int{
//				//	int(v[0]*1000 + 1),
//				//	int(v[1] * 1000),
//				//}]
//				//if !isLand {
//				//	endBuffer = func8(motions, step, v, req.Start)
//				//} else {
//				//	endBuffer = v
//				//}
//			}
//			wgBuffer.Done()
//		}(v, i)
//	}
//	wgBuffer.Wait()
//	return startBuffer, endBuffer
//}
//
//func forward(motions [][2]float64, point []float64, angleIdx int, step float64) bool {
//	for _, offset := range motions {
//		lat := point[0] + offset[1]*step
//		lon := point[1] + offset[0]*step
//
//		_, isLand := landMapBig[[2]int{
//			int(lat*1000 + 1),
//			int(lon * 1000),
//		}]
//		if isLand {
//			return true
//		}
//	}
//	return false
//}
//
//func func8(motions [][]float64, step float64, points map[[2]float64]int, oPoint []float64, gray *sync.Map, start []float64) []float64 {
//	var tempMap = make(map[[2]float64]int)
//	var okPoints [][]float64
//
//	for point := range points {
//		landNum1 := 0
//		for _, offset := range motions {
//			lat := point[0] + offset[1]*step
//			lon := point[1] + offset[0]*step
//			_, isLand := landMapBig[[2]int{
//				int(lat*1000 + 1),
//				int(lon * 1000),
//			}]
//
//			if !isLand {
//				tempMap[[2]float64{
//					utils.Float64Fixed(lat, 4),
//					utils.Float64Fixed(lon, 4),
//				}] = 1
//			} else {
//				landNum1++
//			}
//		}
//		if landNum1 == 0 {
//
//			if len(points) == 1 {
//				okPoints = append(okPoints, []float64{point[0], point[1], getDistance(point[0], point[1], oPoint[0], oPoint[1])})
//
//			} else {
//				angle := math.Atan2(point[0]-start[0], point[1]-start[1]) * 180 / math.Pi
//				if angle < 0 {
//					angle += 360
//				}
//				if angle >= 200 && angle <= 360 {
//					okPoints = append(okPoints, []float64{point[0], point[1], getDistance(point[0], point[1], oPoint[0], oPoint[1])})
//				}
//			}
//		}
//	}
//
//	if len(okPoints) != 0 {
//		minDis := okPoints[0]
//		for _, v := range okPoints {
//			if v[2] < minDis[2] {
//				minDis = v
//			}
//		}
//		return []float64{minDis[0], minDis[1]}
//	} else {
//		return func8(motions, step, tempMap, oPoint, gray, start)
//	}
//}
//
//func func1(motions [][]float64, step float64, points chan []float64, oPoint []float64, gray *sync.Map, start []float64) []float64 {
//
//	var tempPoints = make(chan []float64, len(points)*32)
//	var okPoints = make(chan []float64, len(points))
//	var ch1 = make(chan []float64, len(points))
//	var wgFunc1 sync.WaitGroup
//
//	wgFunc1.Add(1)
//	go func() {
//		for point := range points {
//			ch1 <- point
//		}
//		wgFunc1.Done()
//		close(ch1)
//	}()
//
//	for i := 0; i < 2; i++ {
//		wgFunc1.Add(1)
//		go func() {
//			defer wgFunc1.Done()
//			for point := range ch1 {
//				landNum1 := 0
//				for idx, offset := range motions {
//					lat := point[0] + offset[1]*step
//					lon := point[1] + offset[0]*step
//					_, isLand := landMapBig[[2]int{
//						int(lat*1000 + 1),
//						int(lon * 1000),
//					}]
//					if !isLand {
//
//						grayNum1, isGray := gray.Load([2]int{
//							int(lat*1000 + 1),
//							int(lon * 1000),
//						})
//						if !isGray {
//							tempPoints <- []float64{lat, lon, float64(idx)}
//							//gray[[2]int{
//							//	int(lat*1000 + 1),
//							//	int(lon * 1000),
//							//}] = 0
//							gray.Store([2]int{
//								int(lat*1000 + 1),
//								int(lon * 1000),
//							}, 0)
//						} else {
//							//第二个用到浓度的地方，20这个数随便整的
//							if grayNum1.(int) < 20 {
//								tempPoints <- []float64{lat, lon, float64(idx)}
//								gray.Store([2]int{
//									int(lat*1000 + 1),
//									int(lon * 1000),
//								}, grayNum1.(int)+1)
//							}
//						}
//
//					} else {
//						landNum1++
//					}
//				}
//				//如果其中一个点可以，暂时保存
//				if landNum1 == 0 {
//					//计算point和start的夹角
//					angle := math.Atan2(point[0]-start[0], point[1]-start[1]) * 180 / math.Pi
//					if angle < 0 {
//						angle += 360
//					}
//					//fmt.Println("angle:", angle)
//					if angle >= 200 && angle <= 360 {
//						okPoints <- []float64{point[0], point[1], getDistance(point[0], point[1], oPoint[0], oPoint[1])}
//					}
//				}
//			}
//		}()
//	}
//
//	//打印wgFunc1的数量
//	wgFunc1.Wait()
//
//	if len(okPoints) != 0 {
//		close(okPoints)
//		minDis := <-okPoints
//		for v := range okPoints {
//			if v[2] < minDis[2] {
//				minDis = v
//			}
//		}
//		return []float64{minDis[0], minDis[1]}
//	} else {
//		close(tempPoints)
//		return func1(motions, step, tempPoints, oPoint, gray, start)
//	}
//}
//
//// 获取最近的一个非陆地点
//func getNotLan(point, oPoint []float64) []float64 {
//	//36.0920 120.3171
//	//if point[0] == 36.0921 && point[1] == 120.3206 {
//	//	return []float64{36.0841, 120.2910}
//	//}
//	var motions [][2]float64
//	angle := 32
//	for i := 0; i < angle; i++ {
//		motions = append(motions, [2]float64{math.Cos(float64(i) * 2 * math.Pi / float64(angle)), math.Sin(float64(i) * 2 * math.Pi / float64(angle))})
//	}
//	return get1(motions, 0.001, point, oPoint)
//}
//
//func get1(motions [][2]float64, step float64, point []float64, oPoint []float64) []float64 {
//	var okPoints [][]float64
//	for _, offset := range motions {
//		lat := point[0] + offset[1]*step
//		lon := point[1] + offset[0]*step
//
//		_, isLand := gangkouMap[[2]int{
//			int(lat * 10000),
//			int(lon * 10000),
//		}]
//
//		if !isLand {
//			okPoints = append(okPoints, []float64{lat, lon})
//		}
//	}
//
//	if len(okPoints) != 0 {
//		minDis := okPoints[0]
//		for _, v := range okPoints {
//			if getDistance(v[0], v[1], oPoint[0], oPoint[1]) < getDistance(minDis[0], minDis[1], oPoint[0], oPoint[1]) {
//				minDis = v
//			}
//		}
//		return minDis
//	} else {
//		return get1(motions, step+0.001, point, oPoint)
//	}
//}
//
//func readLandTxt(name string) map[[2]int]struct{} {
//	m := make(map[[2]int]struct{}, 250000)
//	f1, _ := os.Open(name)
//	scanner := bufio.NewScanner(f1)
//	for scanner.Scan() {
//		line := scanner.Text()
//		lat, _ := strconv.ParseFloat(strings.Split(line, ",")[0], 64)
//		lon, _ := strconv.ParseFloat(strings.Split(line, ",")[1], 64)
//		m[[2]int{
//			int(lat),
//			int(lon),
//		}] = struct{}{}
//
//	}
//	f1.Close()
//
//	return m
//}
//
//func readGangkouMap() map[[2]int]struct{} {
//	m := make(map[[2]int]struct{}, 250000*3)
//	fileNames := []string{"36.1_120.3.txt", "36.2_120.3.txt", "35.4_119.5.txt", "36.2_120.5.txt"}
//	for _, fileName := range fileNames {
//		//m1 := readLandTxt("./public/image/0.05/"+fileName)
//		f1, _ := os.Open("./public/image/0.05/" + fileName)
//		scanner := bufio.NewScanner(f1)
//		for scanner.Scan() {
//			line := scanner.Text()
//			lat, _ := strconv.ParseFloat(strings.Split(line, ",")[0], 64)
//			lon, _ := strconv.ParseFloat(strings.Split(line, ",")[1], 64)
//			m[[2]int{
//				int(lat),
//				int(lon),
//			}] = struct{}{}
//		}
//		f1.Close()
//	}
//	return m
//}
